#include "QWaveFormView.h"

#include <assert.h>
#include "QtGui/QPainter.h"
#include "QtGui/QEvent.h"

QWaveFormView::QWaveFormView( QWidget* _parent )
	:	QWidget(_parent)
{
	mDragging = false;
	mDebugText = "debug";
}

void QWaveFormView::SetWaveFormWindow( SampleWindow* waveFormWindow )
{
	mWaveFormWindow = waveFormWindow;
	mWaveFormWindow->registerListener( this );
}

void QWaveFormView::sampleWindowChanged( SampleWindow* sampleWindow )
{
	assert( sampleWindow == mWaveFormWindow );
	update();
}

void QWaveFormView::mousePressEvent( QMouseEvent* mouseEvent )
{
	mDragging = true;

	if ( !mWaveFormWindow )
		return;

	int samplePosInPreDragSampleWindow = mWaveFormWindow->viewPositionToSamplePosition( mouseEvent->x(), width() ); 
	mPreDragSampleWindow = *mWaveFormWindow;
	mPreDragSampleWindow.setPosition( samplePosInPreDragSampleWindow );
}

void QWaveFormView::mouseReleaseEvent( QMouseEvent* mouseEvent )
{
	mDragging = false;
}

void QWaveFormView::mouseMoveEvent( QMouseEvent* mouseEvent )
{
	if ( !mWaveFormWindow )
		return;

	int samplePos = mPreDragSampleWindow.viewPositionToSamplePosition( mouseEvent->x(), width() ); 
	mDebugText = QString("xv=%1  xs=%2").arg( mouseEvent->x() ).arg( samplePos );
	update();
		
		
	if ( mDragging )
	{
		int samplePosInPreDragSampleWindow = mPreDragSampleWindow.viewPositionToSamplePosition( mouseEvent->x(), width() ); 
		int xOffset = mPreDragSampleWindow.getPosition() - samplePosInPreDragSampleWindow;
		
		mWaveFormWindow->setWidth( mPreDragSampleWindow.getWidth() );
		mWaveFormWindow->setPosition( mPreDragSampleWindow.getPosition() + xOffset );
	}
}

void QWaveFormView::wheelEvent(QWheelEvent* wheelEvent)
{
	if ( !mWaveFormWindow )
		return;

	int d = wheelEvent->delta();
	int num = d / 120;
	if ( num==0  )
		return;

	float factor = 1.1f;
	if ( num<0 )
		factor = 1.0 / factor;

	int newWidth = (float)mWaveFormWindow->getWidth() * factor;
	if ( newWidth<10 )
		newWidth = 10;

	mWaveFormWindow->setWidth( newWidth );
}

void QWaveFormView::paintEvent(QPaintEvent* _paintEvent)
{
	QPainter painter(this);
	
	QColor backgroundColor( 180, 180, 180 );
	painter.setBrush(backgroundColor);
	painter.drawRect( 0, 0, width()-1, height()-1 );
	
	if ( !mWaveFormWindow )
		return;
	
	painter.setBrush(Qt::NoBrush);
	QColor lineColor( 0, 0, 0 ); 
	painter.setPen(lineColor);
	painter.setFont(QFont("Arial", 10));
	{
		painter.drawText( 5, 15, mDebugText );

		int zeroLineY = height() / 2;
		int halfHeight = height()/2;
		
		WaveForm::Samples samples;
		mWaveFormWindow->getSamples( samples );
		int numSamples = samples.size();
		
		QVector<QPoint> pointPairs;
		QVector<QPoint> points;
		
		QPoint lastPoint( 0, halfHeight );
		QPoint newPoint;
			
		int startPosInWaveForm = mWaveFormWindow->getPosition();
		for ( int i=0; i<numSamples; ++i )
		{
			int posInWaveForm = startPosInWaveForm + i;
			int x = mWaveFormWindow->samplePositionToViewPosition( posInWaveForm, width() );
			int y = (int)( (  -1.f * (float)samples[i] * (float)halfHeight / 32768.f ) + (float)halfHeight );
			newPoint = QPoint( x, y);
			points.append( newPoint );
			
			pointPairs.append( lastPoint );
			pointPairs.append( newPoint );
			lastPoint = newPoint;
		}
		pointPairs.append( lastPoint );
		pointPairs.append( QPoint(width(), halfHeight) );
			
		painter.setPen( QColor( 170, 170, 170 ) );
		painter.drawLine( 0, zeroLineY, width(), zeroLineY );

		painter.setPen( QColor( 100,100,100 ) );
		painter.drawLines( pointPairs );
		
		QPen pointPen( QColor( 30, 30, 30 ) );
		pointPen.setWidth(2);
		painter.setPen(pointPen);
		painter.drawPoints( points.data(), points.count() );
	}
}
